﻿using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.IO;

namespace LittleBee.DBA
{
	abstract public class DBAccess : IDisposable
	{
		protected Dictionary<string, string> _dctConfig = new Dictionary<string, string>();

		//string _strConnectionString;
		public string ConnectionString { set { ParseConnectionParameters(value); } }

		protected DBConnectionPool _connPool;
		//protected object _connLocker = new object();

		//private DBAccess() { }

		public DBAccess(string strConnectionString, UInt32 nCapcity = 100)
		{
			ConnectionString = strConnectionString;

			_connPool = CreateDBConnectionPool(GetConnectionString("Database"), nCapcity);
		}

		public virtual DbConnection GetConnection()
		{
			return _connPool.GetObject();
		}

		public virtual void PutConnection(DbConnection conn)
		{
			_connPool.PutObject(conn);
		}

		protected abstract DBConnectionPool CreateDBConnectionPool(string strConnection, UInt32 nCapcity = 100);

		private void ParseConnectionParameters(string strConnectionString)
		{
			string[] pairs = strConnectionString.Split(";,\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
			if (pairs != null)
			{
				foreach (var item in pairs)
				{
					string[] keyvalue = item.Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
					if (keyvalue != null && keyvalue.Length == 2)
					{
						keyvalue[0].Trim();
						keyvalue[1].Trim();
						_dctConfig[keyvalue[0]] = keyvalue[1];
					}
				}
			}
		}

		abstract public string GetConnectionString(params object[] aoParams);

		abstract public bool CheckDbExist(string dbname = "");

		abstract public bool CheckTableExist(string tablename);
		
		abstract public bool CreateDatabase(string strDBName);

		abstract public bool DuplicateTable(string tableName);

		abstract public bool ExecuteScriptFile(string strScriptFile);

		/// <summary>
		/// 需要获得多个结果集的时候用该方法，返回DataSet对象。
		/// </summary>
		/// <param name="sql语句"></param>
		/// <returns></returns>
		public abstract DataSet ExecuteDataSet(string sql, params MySqlParameter[] paras);

        /// <summary>
        /// 获得单个结果集时使用该方法，返回DataTable对象。
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>

        public abstract DataTable ExecuteDataTable(string sql, params MySqlParameter[] paras);


        /// <summary>   
        /// 执行一条计算查询结果语句，返回查询结果（object）。   
        /// </summary>   
        /// <param name="SQLString">计算查询结果语句</param>   
        /// <returns>查询结果（object）</returns>   
        public abstract object ExecuteScalar(string SQLString, params MySqlParameter[] paras);

        /// <summary>
        /// 执行Update,Delete,Insert操作
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public abstract int ExecuteNonquery(string sql, params MySqlParameter[] paras);

        /// <summary>
        /// 调用存储过程 无返回值
        /// </summary>
        /// <param name="procname">存储过程名</param>
        /// <param name="paras">sql语句中的参数数组</param>
        /// <returns></returns>
        public abstract int ExecuteProcNonQuery(string procname, params MySqlParameter[] paras);

        /// <summary>
        /// 存储过程 返回Datatable
        /// </summary>
        /// <param name="procname"></param>
        /// <param name="paras"></param>
        /// <returns></returns>
        public abstract DataTable ExecuteProcQuery(string procname, params MySqlParameter[] paras);

		/// <summary>
		/// 一次提交的多语句的事务管理
		/// </summary>
		/// <param name="cmds">命令数组</param>
		/// <returns></returns>
		public abstract bool ExcuteCommandByTran(params string[] cmds);

		/// <summary>
		/// 分批提交的的多语句的事务管理
		/// </summary>
		/// <param name="cmds">命令数组</param>
		/// <returns></returns>
		public abstract bool ExcuteCommandByTran(int nCmdsPerTran, params string[] cmds);

		///分页
		public abstract DataTable ExcuteDataWithPage(string sql, ref int totalCount, params MySqlParameter[] paras);

		public void Dispose()
		{
			_connPool.Dispose();
		}
	}
}
